#include "lpc24xx.h"

#include "config.h" /* Clock config */
#include "uart.h"
#include "type.h"
#include "sdram.h"
#include "sdcard.h"
#include "spi.h"
#include "debug_settings.h"
#include "irq.h"
#include "timer.h"
#include "dma.h"
#include "diskio.h"
#include "ff.h"
#include "sdcard_fs.h"
#include <string.h>
#include "ogg.h"
#include "motion.h"

//#define NOISE_sensed (((AD0GDR >> 6) & 0x3FF) >= 0x00a)
//#define NOISE_sensed 0

// Filesystem setup
// extern from sdcard_fs.c
/*
extern FATFS 	fatDrive;
extern FIL 		file;
extern FRESULT 	res;
extern BYTE 	fs_buffer[4096];
extern DIR 		dir;
extern FILINFO 	fileinfo;
extern char 	filename[13]; // must be at least 13 chars.
*/
//char stringToWrite[] = "BOOM SHAKALAKA\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi ipsum nisi, tincidunt ut ornare vitae, porta non leo. Sed ac sodales tortor. Etiam rutrum dolor ac eros placerat quis porta justo condimentum. Etiam pulvinar, est vel tempor ultrices, orci lectus gravida magna, vel iaculis ligula sapien quis mi. Praesent tempus ultricies lacus. Nunc tristique interdum enim ut consectetur. Etiam sit amet felis vel odio auctor molestie. Donec mollis scelerisque ligula, vel bibendum nulla vulputate eu. Pellentesque diam justo, molestie quis volutpat in, pellentesque at lectus. Duis imperdiet mollis lobortis. Vivamus cursus sodales felis id pulvinar. Aliquam diam odio, blandit id placerat et, viverra at lorem. Praesent nisl arcu, varius ac pretium et, ultricies eget dui. Duis nisi ipsum, aliquam quis vehicula id, fermentum eget lorem.\n\nCras laoreet cursus orci, in dapibus metus hendrerit et. Ut varius fringilla elit, eu congue neque congue at. In convallis justo non diam fringilla volutpat. Proin odio nibh, adipiscing eget vehicula a, dapibus fermentum eros. Praesent vel purus id ante fermentum lacinia et vitae leo. Pellentesque dignissim lectus vel odio tempor varius. Etiam dignissim purus vel leo tristique quis pharetra metus mattis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Etiam lectus enim, imperdiet malesuada pharetra vitae, porta quis sapien. Vestibulum tortor mauris, suscipit eu accumsan ac, consequat posuere risus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin quis vulputate arcu. Fusce sollicitudin augue at dolor auctor eu tincidunt arcu blandit.\n\nEtiam vel lorem in ipsum vestibulum dignissim. Vivamus risus nisl, porta sit amet accumsan quis, porta a arcu. Donec tristique tristique lobortis. Morbi dictum bibendum mauris, ac pharetra neque cursus in. Praesent vitae dolor aliquam nisi auctor commodo. Morbi porttitor rutrum malesuada. Vestibulum consequat metus eget arcu convallis vel luctus dolor condimentum. Donec mattis orci nec eros viverra vitae gravida urna consectetur. Pellentesque ipsum lacus, porta eu viverra rhoncus, mollis ac mi. Etiam elit magna, lacinia nec vehicula ac, dapibus at turpis. Aenean adipiscing, mauris et hendrerit lobortis, nulla sapien hendrerit dui, id cursus tortor diam varius erat.\n\nDuis mattis ipsum sed nibh interdum mattis. Ut tincidunt magna non neque auctor lobortis laoreet turpis tincidunt. Nam convallis, elit eu pretium eleifend, nisi lacus interdum dui, vitae scelerisque lacus lacus ut massa. Integer at sem et lorem facilisis egestas. Cras lobortis magna quis velit ultricies mattis. Proin vel mi massa, eu blandit magna. Pellentesque luctus condimentum nunc, ac volutpat purus malesuada tincidunt. Donec eget orci vel mi viverra dapibus. Sed eu arcu eget quam scelerisque ornare. Morbi lacinia, lacus non sollicitudin pretium, tellus nulla pretium nisi, ut tincidunt leo sapien quis lectus.\n\nMaecenas dignissim, neque a tempor congue, quam magna eleifend nunc, ac consequat sapien quam vitae tellus. Morbi rutrum eros ut ipsum accumsan ac auctor lorem posuere. Pellentesque lorem orci, luctus eu auctor vitae, placerat vitae odio. Maecenas non est sit amet nisl lobortis adipiscing. Etiam tincidunt metus in risus lacinia id posuere mi consequat. Vivamus egestas metus ornare mi venenatis et interdum massa eleifend. Nunc quis risus sed ligula hendrerit dignissim. Nulla faucibus pretium elit, sed gravida tortor interdum quis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed sed massa dui, ut lacinia erat. Donec consectetur elit nec turpis luctus ac ullamcorper felis rutrum. Morbi dolor est, faucibus non congue eu, fringilla non lorem. Suspendisse tellus enim, euismod id auctor a, scelerisque et quam. Fusce ut commodo turpis. Etiam convallis viverra posuere. Vestibulum id ante vel lectus vulputate malesuada. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nec orci metus. In pretium eleifend malesuada. Aenean quis cursus nibh.\n\nMaecenas molestie orci a felis varius eu porta felis pretium. Duis non tellus augue. Morbi gravida vehicula lacinia. Praesent sit amet lacus quis diam eleifend aliquam ut non odio. Donec placerat elit sed nisl blandit ut molestie lectus cursus. Donec consectetur purus id odio ultricies vulputate. Nam quis varius ante. Etiam vitae ipsum eu sem pharetra aliquam sed eget leo. Morbi ac lorem massa, et cursus diam. Maecenas ac lectus metus. Donec quis nibh at nisi convallis aliquet elementum a justo. Phasellus pellentesque est quis sem rhoncus eget sagittis libero auctor. Nulla consequat diam ac quam ullamcorper sagittis. Nunc sit amet leo magna, eu placerat erat.\n\nVivamus magna magna, blandit sed laoreet et, egestas et risus. Duis sodales, sem sollicitudin gravida porttitor, enim ante placerat risus, ut scelerisque ipsum leo eget magna. Quisque arcu odio, dignissim ut gravida consequat, bibendum nec risus. Maecenas gravida nulla eu nulla faucibus quis sagittis mauris tincidunt. Phasellus posuere, lorem a rhoncus vehicula, quam orci dapibus massa, eu aliquet dolor nulla quis nulla. Vivamus congue ultrices lacus sit amet pharetra. Phasellus tristique risus vel tellus tincidunt adipiscing. Sed eros nisl, aliquam ut suscipit et, elementum eu ipsum. Pellentesque vel diam sapien. Suspendisse potenti. Maecenas nec massa mauris, quis vestibulum elit. Nulla facilisi. Nunc porttitor turpis a sem luctus accumsan. Proin adipiscing, eros ac mattis adipiscing, nulla sem malesuada est, ut ultricies nisl libero sit amet ante. Sed est leo, viverra ut hendrerit a, consequat et nunc. Nulla eget purus tellus. Mauris tempus pellentesque orci, a pharetra elit rhoncus feugiat. Fusce commodo sodales posuere. Cras viverra lorem placerat diam adipiscing ac blandit orci lobortis.\n\nDuis gravida ultrices libero. Quisque at turpis nec lorem pretium faucibus. Fusce sed consectetur diam. Mauris velit massa, adipiscing et commodo ut, euismod id.";


// Timer setup
extern DWORD timer0_counter;



static void PLL_init(void) {
	//Step 1, disconnect the PLL if it's connected
	if(PLLSTAT & (1 << 25)) {
		PLLCON = 0x01; // enable PLL
		PLLFEED = 0xaa;
		PLLFEED = 0x55;
	}

	//Step 2, disable the PLL
	PLLCON = 0x00;
	PLLFEED = 0xAA;
	PLLFEED = 0x55;

	//Step 3, enable main oscillator, and wait until main oscillator is usable
	//SCS |= 0x20;
	SCS |= 0x31;

	while(!(SCS & 0x40)); // block until oscillator is usable

	//Step 4, write to the CLKSRCSEL to change the clock source
	CLKSRCSEL = 0x1; //switch over to the main oscillator

	//Step 5, set up values for M and N (M = 144, N = 25 so MSEL = 143 and NSEL = 24)
	PLLCFG = 0x0018008F;
	PLLFEED = 0xAA;
	PLLFEED = 0x55;

	//Step 6, enable the PLL with one feed sequence
	PLLCON = 0x01;
	PLLFEED = 0xAA;
	PLLFEED = 0x55;

	//Step 7, set the CPU clock divider
	CCLKCFG = 0x03; // this is a /4 divider. If we want /8, we do 0x07. /4 = 72MHz

	//Step 8, wait for the PLOCK bit in the PLLSTAT register to be 1
	while( ((PLLSTAT & (1 << 26)) == 0) );

	//Step 9, connect the PLL
	PLLCON = 0x03;
	PLLFEED = 0xAA;
	PLLFEED = 0x55;

	// Check connect bit status before returning
	while(((PLLSTAT & (1 << 25)) == 0));
	return;
}


#if 0
static void FAT_test(void) {
	int i;
	volatile BYTE *byte_wr_ptr;


	fs_initialize_and_mount();

	// Fill SDRAM with something interesting...
	byte_wr_ptr = (BYTE *) SDRAM_BASE_ADDR;
	for(i=0;i<strlen(stringToWrite);i++) { *byte_wr_ptr++ = (BYTE) stringToWrite[i]; }
	byte_wr_ptr = (BYTE *) SDRAM_BASE_ADDR;

	fs_create_file(byte_wr_ptr, strlen(stringToWrite));
}
#endif

int main(void) 
{
	/* Initialize PLL */
	PLL_init();
	
	/* Initialize UART */
	UART0_init();

	xprintf("\n\n___________________________\n");

	init_VIC();
	enable_interrupt();

	FIO3DIRU = 0x1000; // set as output

	//set jam button to have neither a pull up nor pull down resistor.  Already defaults to GPIO input.
	PINMODE7 |= (1 << 13);


	/* Initialize timer.
	   I don't think we'll need this in the real shabang.

	if(init_timer( 0, TIME_INTERVAL )) {
	  xprintf("Timer init completed.\n");
	}
	enable_timer( 0 );
	*/

	/* Initialize SDRAM */
	SDRAM_init();
	//SDRAM_test_byte();


	/* Initialize SDCARD
	 * Warning: SDCARD_test() will DESTROY the filesystem on the card.
	 * If you do this, just pop it into trusty Windows, open up an admin
	 * cmd prompt, and:        format G: /FS:FAT
	 *
	 * Old SDCard init and test was: SDCARD_init(); SDCARD_test();
	 *
	 */
	//FAT_test();

	MOTION_init();
	//MOTION_test();

	OGG_init();

	SPIInit();

	//NOISE_init();
	//NOISE_test();

	fs_initialize_and_mount(); // This used to be in EndOGGRecording(), but it may only be done once.

	while(1) {
		DWORD currStatus;
		int sensed = 0;
		currStatus = AD0GDR;
		currStatus = (currStatus >> 6);
		currStatus &= (0x3FF);
		if (currStatus >= 0x06) {
			//xprintf("Triggered at currStatus: %03x\n", currStatus);
			sensed = 1;
		}

		if(JAM_pressed() || sensed) {
			OGG_init();
			StartRecording();
		}
	}



	xprintf("Got to the end of main.\n");
	while(1);
	return 0; /* never reached */
}
